import { resultFailure, resultSuccess } from '@utils/resultFormatter'
import { prisma } from './index.repo'

export const createGroup = async (name: string, organizationId: string) => {
    try {
        const result = await prisma.group.create({
            data: {
                name,
                organizationId
            }
        })

        return resultSuccess(true, 201, result)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const deleteGroup = async (gId: string) => {
    try {
        const result = await prisma.group.update({
            where: { id: gId },
            data: {
                deletedAt: new Date()
            }
        })

        if (!result) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, result)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateGroup = async (gId: string, name: string) => {
    try {
        const result = await prisma.group.update({
            where: { id: gId },
            data: {
                name
            }
        })

        if (!result) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, result)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readGroupList = async (
    orgId: string | undefined = undefined,
    offset: number = 0,
    limit: number = 10,
    displayDelete: boolean = false
) => {
    try {
        const total = await prisma.group.count({
            where: {
                organizationId: orgId,
                deletedAt: displayDelete ? undefined : null
            }
        })
        const result = await prisma.group.findMany({
            skip: offset,
            take: limit,
            where: {
                deletedAt: displayDelete ? undefined : null
            }
        })

        if (result.length < 1) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, { total, result })
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readGroupListByOrganization = async (
    organizationId: string,
    offset: number = 0,
    limit: number = 10,
    displayDelete: boolean = false
) => {
    try {
        const total = await prisma.group.count({
            where: {
                organizationId,
                deletedAt: displayDelete ? undefined : null
            }
        })

        const result = await prisma.group.findMany({
            skip: offset,
            take: limit,
            where: {
                organizationId,
                deletedAt: displayDelete ? undefined : null
            }
        })

        if (result.length < 1) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, { total, result })
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readGroup = async (gId: string) => {
    try {
        const result = await prisma.group.findUnique({
            where: { id: gId }
        })

        if (!result) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, result)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readGroupMemberList = async (
    gId: string,
    offset: number = 0,
    limit: number = 10,
    displayDelete: boolean = false
) => {
    try {
        const total = await prisma.memberGroup.count({
            where: { groupId: gId, deletedAt: displayDelete ? undefined : null }
        })

        const result = await prisma.memberGroup.findMany({
            skip: offset,
            take: limit,
            include: {
                member: {
                    select: {
                        id: true,
                        identifier: true,
                        realName: true,
                        nickName: true,
                        wxOpenId: true
                    }
                }
            },
            where: { groupId: gId, deletedAt: displayDelete ? undefined : null }
        })

        if (!result) return resultFailure(false, 404, 'Group members not found')

        return resultSuccess(true, 200, { total, result })
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 添加成员到组
 * @param gId 组ID
 * @param memberIds 成员ID列表
 * @param orgId 组织ID
 */
export const addMembersToGroup = async (gId: string, memberIds: string[], orgId: string) => {
    try {
        const result = await prisma.memberGroup.createMany({
            data: memberIds.map(memberId => ({
                groupId: gId,
                memberId,
                organizationId: orgId
            })),
            skipDuplicates: true
        })

        return resultSuccess(true, 201, result, `${result.count} members added to group successfully`)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 从组中移除成员
 * @param gId 组ID
 * @param memberIds 成员ID列表
 */
export const removeMembersFromGroup = async (gId: string, memberIds: string[]) => {
    try {
        const result = await prisma.memberGroup.updateMany({
            where: {
                groupId: gId,
                memberId: { in: memberIds }
            },
            data: {
                deletedAt: new Date()
            }
        })

        return resultSuccess(true, 200, result, `${result.count} members removed from group successfully`)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 检查组是否存在
 * @param gId 组ID
 */
export const checkGroupExists = async (gId: string) => {
    try {
        const result = await prisma.group.findUnique({
            where: { id: gId }
        })

        if (!result) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, true, 'Group exists')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

/**
 * 读取组的详细信息（包括成员和关联的事件）
 * @param gId 组ID
 */
export const readGroupDetail = async (gId: string) => {
    try {
        const result = await prisma.group.findUnique({
            where: { id: gId },
            include: {
                organization: {
                    select: {
                        id: true,
                        name: true
                    }
                },
                MemberGroup: {
                    where: { deletedAt: null },
                    include: {
                        member: {
                            select: {
                                id: true,
                                identifier: true,
                                realName: true,
                                nickName: true
                            }
                        }
                    }
                },
                EventGroup: {
                    where: { deletedAt: null },
                    include: {
                        event: {
                            select: {
                                id: true,
                                title: true,
                                startAt: true,
                                endAt: true
                            }
                        }
                    }
                },
                EventCombinationGroup: {
                    where: { deletedAt: null },
                    include: {
                        eventCombination: {
                            select: {
                                id: true,
                                name: true
                            }
                        }
                    }
                }
            }
        })

        if (!result) return resultFailure(false, 404, 'Group not found')

        return resultSuccess(true, 200, result)
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}
